use std::thread;
use std::time::Duration;
use crate::guess_game::guessing_game;

mod guess_game;

fn main() {
    // println!("Hello, world!");
    // test02()
    // test03()
    // test04()
    // test05()
    // let s = String::from("abcd");
    // println!("{}", &s[1..3]);
    // for x in s.chars() {
    //     println!("{x}")
    // };
    // let r1 = Rectangle::new(1, 2);
    // r1.can_hold(&Rectangle::new(2,3));
    // Rectangle::area(&r1);
    // test14();
    // concat_str("a");
    // let s = Student {
    //     name: "aa".to_string(),
    //     age: 1,
    // };
    // println!("name={}, age={}", s.name, s.age);
    // test16();

    let str = "123";
    let str2: String = str.into();
    println!("{}", str);
    println!("{}", str2);
}

#[test]
fn test17() {
    println!("This is a Test")
}

fn test16() {
    let duration = Duration::from_millis(3000);

    let thread1 = thread::spawn(move || {
        thread::sleep(duration);
        println!("线程1执行完成")
    });

    let thread2 = thread::spawn(move || {
        thread::sleep(duration);
        println!("线程2执行完成")
    });

    thread1.join().unwrap();
    thread2.join().unwrap();

    println!("主线程执行完成")
}

struct Example(i32);

impl Iterator for Example {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        return if self.0 % 10 != 0 {
            self.0 += 1;
            Some(self.0)
        } else {
            self.0 += 1;
            None
        };
    }
}

fn test15() {
    let example = Example(5);
    for item in example.into_iter() {
        println!("item = {}", item);
    }
}

#[derive(Debug)]
struct Student {
    name: String,
    age: u16,
}

impl Drop for Student {
    fn drop(&mut self) {
        println!("Student Drop!")
    }
}

// 返回&str时需要加上生命周期
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

fn concat_str(x: &str) -> &str {
    // 当从一个函数/方法返回一个引用时，返回类型的生命期参数需要与其中一个参数的生命期参数相匹配
    // 不能只返回局部变量
    let local = String::from("rust");
    // return &local;
    return x;
}

fn test14() {
    let str1 = "rust";
    let string1 = String::from(str1);
    // fn to_string(&self) -> String {
    //     String::from(self)
    // }
    let string2 = str1.to_string();
    println!("栈地址：{:p}, 堆地址：{:?}", &str1, str1.as_ptr());
    println!("栈地址：{:p}, 堆地址：{:?}", &string1, string1.as_ptr());
}

fn test13() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("read_line error!");
    println!("你输入的内容是：{input}")
}

fn test12() {
    let a: i32 = 5;
    let b: f64 = 3.5;
    let c: f64 = a as f64;
    dbg!(c + b);
}

fn test11() {
    dbg!("Hello dbg");
    println!("Hello println");
    eprintln!("Hello eprintln");
}

fn test10() {
    let args = std::env::args();
    for arg in args {
        println!("arg={}", arg)
    }
    std::process::exit(0);
}

fn test05() {
    let r1 = Rectangle::new(3, 4);
    println!("r1.area={}", r1.area());
    let r2 = Rectangle::new(2, 3);
    println!("r1={:?}, r2={:#?}", r1, r2);
    let x = r1.can_hold(&r2);
    println!("{x}")
}

#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn new(w: u32, h: u32) -> Self {
        Self {
            width: w,
            height: h,
        }
    }
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn can_hold(&self, other: &Rectangle) -> bool {
        return self.width >= other.width && self.height >= other.height;
    }
}

fn test04() {
    let s = String::from("abc d");
    let word = first_word(&s);
    println!("first_word = {word}")
}

fn test01() {
    guessing_game()
}

fn test02() {
    let s1 = String::from("hello");
    let s2 = s1;
    // println!("{}, world", s1) //error:value borrowed here after move
    println!("{}, world", s2)
}

fn test03() {
    let s = String::from("hello");  // s 进入作用域
    takes_ownership(s);             // s 的值移动到函数里 ...
    // ... 所以到这里不再有效
    let x = 5;                      // x 进入作用域
    makes_copy(x);                  // x 应该移动函数里，
    // 但 i32 是 Copy 的，
    // 所以在后面可继续使用 x
    // println!("s={s}");
    println!("x={x}");
} // 这里，x 先移出了作用域，然后是 s。但因为 s 的值已被移走，
// 没有特殊之处

fn takes_ownership(some_string: String) { // some_string 进入作用域
    println!("{}", some_string);
} // 这里，some_string 移出作用域并调用 `drop` 方法。
// 占用的内存被释放

fn makes_copy(some_integer: i32) { // some_integer 进入作用域
    println!("{}", some_integer);
} // 这里，some_integer 移出作用域。没有特殊之处

fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}